<template>
  <div class="wrapper" id="container"></div>
</template>
<script>
import {
  ExtensionCategory,
  Graph,
  register,
  treeToGraphData
} from '@antv/g6'
import { AssignColorByBranch, ArrangeEdgeZIndex } from './lib/clazz'
import { Text } from '@antv/g'
import { flow } from './lib/flow'
export default {
  data() {
    return {
      graph: null,
      textShape: null,
    }
  },
  methods: {
    initGraph() {
      if (this.graph != null) {
        this.graph.clear()
        this.graph.destroy()
        this.graph = null
      }
      register(
        ExtensionCategory.TRANSFORM,
        'assign-color-by-branch',
        AssignColorByBranch
      )
      register(
        ExtensionCategory.TRANSFORM,
        'arrange-edge-z-index',
        ArrangeEdgeZIndex
      )

      const graph = new Graph({
        container: 'container',
        width: document.getElementById('container').clientWidth, // Number，必须，图的宽度
        height: document.getElementById('container').clientHeight, // Number，必须，图的高度
        autoFit: 'view',
        fitCenter: true,
        data: treeToGraphData(flow),
        padding: 10,
        node: {
          type: 'rect',
          style: (d) => {
            const style = {
              radius: 8,
              size: this.getNodeSize(d.id, d.depth),
              labelText: d.id,
              labelPlacement: 'right',
              labelFontFamily: 'Gill Sans',
            }

            if (d.depth === 0) {
              Object.assign(style, {
                fill: '#EFF0F0',
                labelFill: '#262626',
                labelFontWeight: 'bold',
                labelFontSize: 24,
                labelOffsetY: 4,
                labelPlacement: 'center',
                labelLineHeight: 24,
              })
            } else if (d.depth === 1) {
              Object.assign(style, {
                labelFontSize: 18,
                labelFill: '#fff',
                labelFillOpacity: 0.9,
                labelOffsetY: 5,
                labelPlacement: 'center',
                fill: d.style?.color,
              })
            } else {
              Object.assign(style, {
                fill: 'transparent',
                labelFontSize: 16,
                labeFill: '#262626',
              })
            }
            return style
          },
        },
        edge: {
          type: 'polyline',
          style: {
            lineWidth: 3,
            stroke: function (data) {
              return this.getNodeData(data.target).style.color || '#99ADD1'
            },
          },
        },
        layout: {
          type: 'fishbone',
          direction: 'LR',
          hGap: 40,
          vGap: 60,
        },
        behaviors: ['zoom-canvas', 'drag-canvas'],
        transforms: ['assign-color-by-branch', 'arrange-edge-z-index'],
      })

      graph.render()
      this.graph = graph

      window.addEventListener('resize', () => {
        graph.onResize(
          document.getElementById('container').clientWidth,
          document.getElementById('container').clientHeight
        )
        graph.fitCenter()
      })
    },
    getNodeSize(id, depth) {
      const FONT_FAMILY = 'system-ui, sans-serif'
      return depth === 0
        ? [
            this.measureText({
              text: id,
              fontSize: 24,
              fontWeight: 'bold',
              fontFamily: FONT_FAMILY,
            }) + 80,
            70,
          ]
        : depth === 1
        ? [
            this.measureText({
              text: id,
              fontSize: 18,
              fontFamily: FONT_FAMILY,
            }) + 50,
            42,
          ]
        : [2, 30]
    },
    measureText(style) {
      let textShape = this.textShape
      if (!textShape) textShape = new Text({ style })
      textShape.attr(style)
      return textShape.getBBox().width
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.initGraph()
    })
  },
}
</script>
<style lang="scss" scoped>
</style>./lib/clazz